package com.ocom.ugcapi.controller;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.ocom.common.constant.WxServiceUrl;
import com.ocom.common.entity.company.EntityComDockApi;
import com.ocom.common.entity.company.EntityCompanyConfig;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.company.GetReplyApiParaRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.*;
import com.ocom.common.vo.PersonVo;
import com.ocom.common.vo.human.UserInfoVo;
import com.ocom.common.vo.ugcapi.GzhUserInfo;
import com.ocom.redis.util.RedisUtil;
import com.ocom.ugcapi.client.CompanyClientService;
import com.ocom.ugcapi.client.HumanClientService;
import com.ocom.ugcapi.config.RsaConfig;
import com.ocom.ugcapi.util.RSAHelper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.*;

/**
 * @Description: TODO
 * @Author: 朱晖
 * @Date: 2023/5/22
 **/
@Slf4j
@RestController
public class CcbController {

	@Resource
	private RedisUtil redisUtil;

	@Autowired
	CompanyClientService companyClientService;

	@Autowired
	HumanClientService humanClientService;


	//绑定码 绑定 推送建行H5
	@PostMapping(WxServiceUrl.URL_ccbBindUser)
	public Result bindUser(@RequestBody Map<String, Object> map) throws ParseException, IOException {
		log.info("bindUser: 【{}】",map);
//		JHh5 jHh5 = getCompany((String) map.get("loginCode"));
//		if(jHh5.getCode()!=0){
//			return ResultUtil.info(501,jHh5.getMsg());
//		}
		GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
		getReplyApiParaRequest.setComAppid((String) map.get("campusId"));
		getReplyApiParaRequest.setDockCode("ccbplatform");
		getReplyApiParaRequest.setDockApiCode("ccbplatform#app");
		getReplyApiParaRequest.setKeyType(0);
		Result result2 = companyClientService.getReplyApiPara(getReplyApiParaRequest);

		if (result2.getCode() != 200) {
			return result2;
		}

		String key2 = "tbk0Xa67cEePvv14g5Pf1MPzIceQMN14"; // 密钥（8 字节）


		String username = (String) map.get("username");
		String password = (String) map.get("password");

		if(!CommonUtil.isNull(username)){
			username = HexUtil.decodeHexStr(username);
			username = SecureUtil.des(key2.getBytes(StandardCharsets.UTF_8)).decryptStr(username);
		}
		if(!CommonUtil.isNull(password)){
			password = HexUtil.decodeHexStr(password);
			password = SecureUtil.des(key2.getBytes(StandardCharsets.UTF_8)).decryptStr(password);
		}

		EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result2.getData()), EntityComDockApi.class);

		EntityPersonnelInfo entityPersonnelInfo = getPerson(entityComDockApi.getComId(), (String) map.get("pCode"), username );

		if (entityPersonnelInfo == null || !entityPersonnelInfo.getPPwd().equals(password)) {
			return ResultUtil.error(ResultEnum.Err_311);
		}

		try {
			if(map.get("phone")!=null && CommonUtil.isNull(entityPersonnelInfo.getPPhone())){
				PersonVo personVo=new PersonVo();
				personVo.setComId(entityPersonnelInfo.getComId());
				personVo.setPId(entityPersonnelInfo.getPId());
				personVo.setPPhone((String) map.get("phone"));
				humanClientService.UpdatePerson(personVo);
			}
		}catch (Exception e){
			log.info("同步手机号: 【{}】",e);
		}

		/**
		 * bindCode	绑定码	string		是
		 * campusId	学校应用编号	string		是
		 * pName	用户姓名	string		是
		 * pCode	用户编号	string		是
		 */

		JSONObject jsonObject = new JSONObject();
		jsonObject.put("serverId", "ocom001");
		jsonObject.put("nonceStr", RandomUtil.getRandomString(32));
		jsonObject.put("pCode", entityPersonnelInfo.getPCode());
		jsonObject.put("pName", entityPersonnelInfo.getPName());
		jsonObject.put("campusId", (String) map.get("campusId"));
		jsonObject.put("bindCode", (String) map.get("loginCode"));
		jsonObject.put("timestamp", System.currentTimeMillis());


		SortedMap<String, Object> parameters = JSON.parseObject(JSON.toJSONString(jsonObject), SortedMap.class);
		String sign = SignUtils.createSign(parameters, "tJhhgLE7vSpW9NJ0mP9nWpCAqlY6RKod");
		jsonObject.put("sign", sign.toUpperCase(Locale.ROOT));

		RequestUtil requestUtil = new RequestUtil();
		Map<String, String> resmap = requestUtil.doPostJson("http://abc.ocomtraffic.com/app/bind/bindUser", JSON.toJSONString(jsonObject));
		JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(resmap));
		if (jsonObject1.getInteger("code") != 0) {
			//异常  返回
			log.info("公众号JH获取单位2【{}】", resmap);
			return ResultUtil.info(501, jsonObject1.getString("msg"));
		}
		Map<String,Object> resMap =new HashMap<>();

		String key = "";
		if(CommonUtil.isNull(entityPersonnelInfo.getPPhone())){
			key = RandomUtil.getRandomString(30);
			redisUtil.set("UpdateUserPhone:" + key,entityPersonnelInfo,300l);
		}
	//	resMap.put("updatePhone",CommonUtil.isNull(entityPersonnelInfo.getPPhone()));
		resMap.put("updatePhone", false );
		resMap.put("sence",key);
		return ResultUtil.success(resMap);
	}

	//bindUser

	//获取token  或者  获取绑定单位信息
	@PostMapping(WxServiceUrl.URL_ccbUserLogin)
	public Result icbcUserLogin(@RequestBody Map<String, Object> map) throws ParseException, IOException {
		log.info("icbcUserLogin: 【{}】",map);
		if (CommonUtil.isNull((String) map.get("loginCode"))) {
			return ResultUtil.info(501, "loginCode不能为空");
		}

		Map<String, Object> resMap = new HashMap<>();
		resMap.put("comId", -1l);
		resMap.put("token", null);
		resMap.put("comInfo", null);

		//1 获取token  2 获取绑定单位信息

		//2 绑定码 返回单位Id
		Integer type = (Integer) map.get("type");
		if (type == 2) {
			GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
			getReplyApiParaRequest.setComAppid((String) map.get("campusId"));
			getReplyApiParaRequest.setDockCode("ccbplatform");
			getReplyApiParaRequest.setDockApiCode("ccbplatform#app");
			getReplyApiParaRequest.setKeyType(0);
			Result result2 = companyClientService.getReplyApiPara(getReplyApiParaRequest);

			if (result2.getCode() != 200) {
				return result2;
			}
			EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result2.getData()), EntityComDockApi.class);
			resMap.put("comId", entityComDockApi.getComId());
			Result result = companyClientService.getCompanyInfoById(entityComDockApi.getComId());
			resMap.put("comInfo", result.getData());
			return ResultUtil.success(resMap);
		}

		Object ob = redisUtil.get("JHAPP:" + (String) map.get("loginCode"));
		if (ob != null) {
			return ResultUtil.success(ob);
		}

		JHh5 jHh5 = getCompany((String) map.get("loginCode"));
		if (jHh5.getCode() != 0) {
			return ResultUtil.info(501, jHh5.getMsg());
		}

		//单位不存在
		if (jHh5.getComId() == null || jHh5.getComId() <= 0l) {
			return ResultUtil.error(ResultEnum.Err_301);
		}

		resMap.put("comId", jHh5.getComId());
		Result result = companyClientService.getCompanyInfoById(jHh5.getComId());
		resMap.put("comInfo", result.getData());

		//type == 1 返回token

		//人员不存在
		if (CommonUtil.isNull(jHh5.getPCode())) {
			return ResultUtil.error(ResultEnum.Err_303);
		}

		EntityPersonnelInfo entityPersonnelInfo = getPerson(jHh5.getComId(), jHh5.getPCode(), null);
		if (entityPersonnelInfo == null) {
			return ResultUtil.error(ResultEnum.Err_303);
		}

		log.info("建行获取人员 【{}】",entityPersonnelInfo);

		GzhUserInfo user = new GzhUserInfo();
		Gson gson = new Gson();

		user.setComId(entityPersonnelInfo.getComId());
		user.setPId(entityPersonnelInfo.getPId());
		user.setPasswordCorrect(true);

//		if(!CommonUtil.isNull(entityPersonnelInfo.getPPwd()) &&
//				!HandlePasswordUtil.isWeekPassword(entityPersonnelInfo.getPPwd())){
//			user.setPasswordCorrect(false);
//		}
		if(!CommonUtil.isNull(entityPersonnelInfo.getPPwd()) ){
			Result<List<EntityCompanyConfig>> result3 = companyClientService.getCompanyConfig(entityPersonnelInfo.getComId(),"allowWeakPasswords");
			log.info("读取到配置 6KyTqy3c 【{}】【{}】",entityPersonnelInfo,result3);
			if(result3.getCode()!=200 || result3.getData() ==null || !"true".equals(result3.getData().get(0).getConfig()) ){
				List<String> errors = PasswordValidator.validatePassword(entityPersonnelInfo.getPPwd());
				if (!errors.isEmpty()) {
					user.setPasswordCorrect(false);
				}
				log.info("读取到配置 6KyTqy3c 【{}】【{}】",entityPersonnelInfo,user);
			}else{
				user.setPasswordCorrect(true);
			}
		}

		user.setLoginSecret(RandomUtil.getRandomString(20));
		user.setStatus(0);
		user.setPPhone(entityPersonnelInfo.getPPhone());
		String token;
		try {
//            token = encryptOpenId(user.getAppId()+"##"+user.getOpenId());
			token = RSAHelper.encipher(gson.toJson(user), RsaConfig.publicKey, 200);
			log.info("登录Token:" + token);
			redisUtil.set("gzhToken:" + user.getComId() + ":" + user.getPId(), gson.toJson(user),31536000l);
		} catch (Exception e) {
			log.info("登录生成token异常 【{}】", e);
			return ResultUtil.error(ResultEnum.Err_4003);
		}

		resMap.put("passwordCorrect", user.getPasswordCorrect());
		resMap.put("token", token);
		redisUtil.set("JHAPP:" + (String) map.get("loginCode"), resMap, 3600l * 4l);
		return ResultUtil.success(resMap);
	}


	private JHh5 getCompany(String loginCode) throws ParseException, IOException {
		try {
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("serverId", "1");
			jsonObject.put("nonceStr", RandomUtil.getRandomString(32));
			jsonObject.put("loginCode", loginCode);
			jsonObject.put("timestamp", System.currentTimeMillis());

			SortedMap<String, Object> parameters = JSON.parseObject(JSON.toJSONString(jsonObject), SortedMap.class);
			String sign = SignUtils.createSign(parameters, "tJhhgLE7vSpW9NJ0mP9nWpCAqlY6RKod");

			jsonObject.put("sign", sign.toUpperCase(Locale.ROOT));
			RequestUtil requestUtil = new RequestUtil();
			Map<String, String> resmap = requestUtil.doPostJson("http://abc.ocomtraffic.com/app/campus/userLogin", JSON.toJSONString(jsonObject));
			JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(resmap));

			log.info("调用建行H5 【{}】 【{}】",jsonObject,resmap);
			if (jsonObject1.getInteger("code") != 0) {
				//异常  返回
				log.info("公众号JH获取单位2【{}】", resmap);
				return new JHh5(jsonObject1.getInteger("code"), jsonObject1.getString("msg"), null, null, null, null);
			}
			if (CommonUtil.isNull(jsonObject1.getString("data"))) {
				return new JHh5(500, "学校编号空", null, null, null, null);
			}
			JSONObject jsonObject2 = JSON.parseObject(JSON.toJSONString(jsonObject1.get("data")));

			if (CommonUtil.isNull(jsonObject2.getString("campusId"))) {
				return new JHh5(500, "学校编号空", null, null, null, null);
			}
			/**
			 * campusId	学校应用编号	string		是
			 * pName	用户姓名	string		是
			 * pCode	用户编号	string		是
			 */
			GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
			getReplyApiParaRequest.setComAppid(jsonObject2.getString("campusId"));
			getReplyApiParaRequest.setDockCode("ccbplatform");
			getReplyApiParaRequest.setDockApiCode("ccbplatform#app");
			getReplyApiParaRequest.setKeyType(0);
			Result result2 = companyClientService.getReplyApiPara(getReplyApiParaRequest);

			if (result2.getCode() != 200) {
				return new JHh5(result2.getCode(), result2.getMsg(), jsonObject2.getString("campusId"), null, null, null);
			}
			EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result2.getData()), EntityComDockApi.class);

			return new JHh5(0, "succ", jsonObject2.getString("campusId"), entityComDockApi.getComId(), jsonObject2.getString("pName"), jsonObject2.getString("pCode"));
		} catch (Exception e) {
			log.info("调用建行h5平台异常【{}】", e);
			return null;
		}
	}

	private EntityPersonnelInfo getPerson(Long comId, String pCode, String pName) {
		try {
			UserInfoVo userInfoVo = new UserInfoVo();
			userInfoVo.setComId(comId);
			userInfoVo.setPCode(pCode);
			if (!CommonUtil.isNull(pName)) {
				userInfoVo.setPName(pName);
			}
			userInfoVo.setOnlyOne(true);
			Result result3 = humanClientService.PersonnelGetPersonInfo(userInfoVo);
			if (result3.getCode() != 200 || result3.getData() == null) {
				log.info("公众号JH获取人员异常1【{}】", result3);
				return null;
			}
			EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result3.getData()), EntityPersonnelInfo.class);
			return entityPersonnelInfo;
		} catch (Exception e) {
			log.info("公众号JH获取人员异常2【{}】", e);
			return null;
		}

	}


	@Data
	private static class JHh5 {
		//0正常  1 异常
		Integer code;
		String msg;
		String campusId;
		String pName;
		String pCode;
		Long comId;

		public JHh5(Integer code, String msg, String campusId, Long comId, String pName, String pCode) {
			this.code = code;
			this.msg = msg;
			this.campusId = campusId;

			this.comId = comId;
			this.pName = pName;
			this.pCode = pCode;
		}
	}

	//更新手机
	@Deprecated  //后续是通过签约后更新掉用户的手机号
	@PostMapping(WxServiceUrl.URL_ccbUpdatePhone)
	public Result updateUserPhone(@RequestBody Map<String, Object> map) {

		String key = (String) map.get("scene");
		String phone = (String) map.get("phone");
		String code = (String) map.get("code");
		Object  obj  = redisUtil.get("UpdateUserPhone:" +  key);

		if(obj==null){
			return ResultUtil.error(ResultEnum.Err_3084);
		}

		EntityPersonnelInfo entityPersonnelInfo = (EntityPersonnelInfo) obj;

		//step 1 验证手机号
		Object checkCode =  redisUtil.get("gzh:signCode:"+entityPersonnelInfo.getComId()+":"+phone+":" +code);
		if(checkCode == null){
			return ResultUtil.error(ResultEnum.Err_2002);
		}

		PersonVo personVo=new PersonVo();
		personVo.setComId(entityPersonnelInfo.getComId());
		personVo.setPId(entityPersonnelInfo.getPId());
		personVo.setPPhone(phone);
		Result result = humanClientService.UpdatePersonNotCheckPhone(personVo);

		if(result.getCode()==200){
			redisUtil.del("gzh:signCode:"+entityPersonnelInfo.getComId()+":"+phone+":" +code,"UpdateUserPhone:" +  key);
		}

		return result;
	}



}
